'''
Created on Sep 14, 2011

@author: nktran
'''

import utils

class Table:
    """
    The <code>Table<code> class stores information about the prefix-closed
    set PC, suffix-closed set SC and a finite function mapping ((PC U PC.A).SC)
    to {0,1}
    """
    
    def __init__(self):
        """
        Default constructor
        
        @var prefix: prefix-closed set
        @var suffix: suffix-closed set
        @var func: function mapping   
        """
        self.prefix = set()
        self.suffix = set()
        self.func = dict()
        
    def add_to_prefix(self, pre_set):
        """
        Add all elements of a set into prefix set
        
        @param pre_set: input set
        """
        for pre in pre_set:
            self.prefix.add(pre)
        
    def add_to_suffix(self, suf_set):
        """
        Add all elements of a set into suffix set
        
        @param suf_set: input set 
        """
        for suf in suf_set:
            self.suffix.add(suf)
    
    def update_cell(self, pre, suf, val):
        """
        Update the value of the cell [pre,suf] in the table
        
        @param pre: the row of the cell
        @param suf: the column of the cell
        @param val: value to be updated   
        """
        if self.func.has_key(pre):
            self.func[pre][suf] = val
        else:
            self.func[pre] = {suf:val}        
            
    def find_new_prefix(self, alphabet):
        """
        Find prefix pre1 and alphabet a such that row(pre1+a) is different 
        from row(pre) for all pre in prefix set
        
        @return: pref + a
        """
        for pre1 in self.prefix:
            for a in alphabet:
                if pre1+a in self.prefix:
                    continue
                flag = True
                has_key = self.func.has_key(pre1+a)                            
                for pre in self.prefix:
                    if has_key and self.func[pre1+a] == self.func[pre]:
                        flag = False
                        break
                if flag:
                    return pre1+a   
        return None                
    
    def find_new_suffix(self, alphabet):
        """
        Find prefix pre1 and pre2, alphabet a and suffix suf such that
        row(pre1) = row(pre2) and T(pre1+a+suf) != T(pre2+a+suf)
        
        @return: a+suf        
        """
        for pre1 in self.prefix:
            for pre2 in self.prefix:                        
                if pre1 != pre2 and self.func[pre1] == self.func[pre2]:
                    for suf in self.suffix:                                
                        for a in alphabet:
                            if self.func[pre1+a][suf] != self.func[pre2+a][suf] \
                                    and a+suf not in self.suffix:
                                return a+suf
        return None
        
    def toString(self):
        """
        Return table into string
        """
        #prefix
        output = "Prefix: {%s} \n" % (", ".join(self.prefix))
        output = output + "Suffix: {%s} \n" % (", ".join(self.suffix))
        for pre in self.func.keys():
            for suf in self.func[pre].keys():
                output = output + "T[%s][%s] = %s \n" % (utils.format(pre), 
                                        utils.format(suf), self.func[pre][suf])
        
        return output
        